package com.example.lin.day9_10.day_9_10.utils;

        import android.os.Bundle;
        import android.os.Handler;
        import android.os.Message;
        import android.support.annotation.NonNull;
        import android.text.TextUtils;
        import android.util.Log;

        import java.io.BufferedInputStream;
        import java.io.BufferedOutputStream;
        import java.io.File;
        import java.io.FileOutputStream;
        import java.io.IOException;
        import java.io.InputStream;
        import java.util.Map;
        import java.util.Set;

        import okhttp3.Call;
        import okhttp3.Callback;
        import okhttp3.FormBody;
        import okhttp3.OkHttpClient;
        import okhttp3.Request;
        import okhttp3.Response;
        import okhttp3.ResponseBody;

public class OkUtils {

    private OkUtils() {
    }

    private static final OkHttpClient CLIENT = new OkHttpClient();

    static {
        //TODO 对 OkHttpClient 的配置
    }

    public interface OnOkCallback {
        void onFailure(IOException e);

        void onResponse(String response);
    }

    public interface OnOkDownloadCallback extends OnOkCallback {
        void onProgress(float progress);

        void onResponse(String filepath);
    }

    private static final Handler HANDLER = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {

            return false;
        }
    });


    public static void get(String url, @NonNull final OnOkCallback onOkCallback) {
        Request build = new Request.Builder().url(url)
                .get()
                .build();
        CLIENT.newCall(build).enqueue(new Callback() {
            /**
             * 请求失败
             * @param call 连接对象
             * @param e 失败的异常
             */
            @Override
            public void onFailure(Call call, final IOException e) {
                //该方法在子线程中被调用
                HANDLER.post(new Runnable() {
                    @Override
                    public void run() {
                        onOkCallback.onFailure(e);
                    }
                });
            }

            /**
             * 请求成功
             * @param call 连接对象
             * @param response 响应结果
             * @throws IOException
             */
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //该方法在子线程中被调用
                final String s = response.body().string();
                HANDLER.post(new Runnable() {
                    @Override
                    public void run() {
                        onOkCallback.onResponse(s);
                    }
                });
            }
        });
    }


    public static void post(@NonNull String url, @NonNull Map<String, String> params, @NonNull final OnOkCallback onOkCallback) {
        FormBody.Builder builder = new FormBody.Builder();
        Set<Map.Entry<String, String>> entries = params.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            builder.addEncoded(entry.getKey(), entry.getValue());
        }
        FormBody formBody = builder.build();

        Request request = new Request.Builder().url(url).post(formBody).build();
        CLIENT.newCall(request).enqueue(new Callback() {
            /**
             * 请求失败
             * @param call 连接对象
             * @param e 失败的异常
             */
            @Override
            public void onFailure(Call call, final IOException e) {
                //该方法在子线程中被调用
                HANDLER.post(new Runnable() {
                    @Override
                    public void run() {
                        onOkCallback.onFailure(e);
                    }
                });
            }


            /**
             * 请求成功
             * @param call 连接对象
             * @param response 响应结果
             * @throws IOException
             */
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //该方法在子线程中被调用
                final String s = response.body().string();
                HANDLER.post(new Runnable() {
                    @Override
                    public void run() {
                        onOkCallback.onResponse(s);
                    }
                });
            }
        });
    }


    public static final void download(@NonNull final String url, @NonNull final String dir, @NonNull final OnOkDownloadCallback onOkDownloadCallback) {
        Request request = new Request.Builder().url(url).get().build();
        CLIENT.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, final IOException e) {
                HANDLER.post(new Runnable() {
                    @Override
                    public void run() {
                        onOkDownloadCallback.onFailure(e);
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                ResponseBody body = response.body();//得到响应体
                InputStream inputStream = body.byteStream();//获取服务器的输入流
                //获取私有的外部存储的跟目录,//路径:SD卡的共有的根目录/Android/data/应用程序包名/files
                String fileName = getHeaderFileName(response);
                if (fileName == null) {
                    fileName = getUrlFileName(url);
                }
                long max = body.contentLength();

                final File file = new File(dir, fileName);
                FileOutputStream fos = new FileOutputStream(file);
                BufferedInputStream bis = new BufferedInputStream(inputStream);
                BufferedOutputStream bos = new BufferedOutputStream(fos);
                byte[] buf = new byte[1024];
                int len;
                long sum = 0;
                while ((len = bis.read(buf)) != -1) {
                    bos.write(buf, 0, len);
                    sum += len;
                    final float progress = 1.0f * sum / max;
                    HANDLER.post(new Runnable() {
                        @Override
                        public void run() {
                            onOkDownloadCallback.onProgress(progress);
                        }
                    });

                }
                bis.close();
                bos.flush();
                bos.close();
                HANDLER.post(new Runnable() {
                    @Override
                    public void run() {
                        onOkDownloadCallback.onResponse(file.getAbsolutePath());
                    }
                });
            }
        });
    }

    /**
     * 解析文件头 获得文件名称
     * Content-Disposition:attachment;filename=FileName.txt
     * Content-Disposition: attachment; filename*="UTF-8''%E6%9B%BF%E6%8D%A2%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A.pdf"
     */
    private static String getHeaderFileName(Response response) {
        String dispositionHeader = response.header("Content-Disposition");
        if (!TextUtils.isEmpty(dispositionHeader)) {
            return dispositionHeader.substring(dispositionHeader.indexOf("=") + 1);
        }
        return null;
    }

    /**
     * 通过 Url 取出 文件名字
     * String url = "http://192.168.3.143:8080/file/Fade.mp3";
     *
     * @param url
     * @return
     */
    private static String getUrlFileName(String url) {
        if (!TextUtils.isEmpty(url)) {
            int i = url.lastIndexOf("/");
            if (i > 0) {
                return url.substring(i + 1);
            }
        }
        return null;
    }
}
